//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;

namespace EntLibContrib.Resource.Configuration
{
	/// <summary>
	/// Configuration object for Custom Providers.
	/// </summary>
	[Assembler(typeof(CustomProviderAssembler<IResourceProvider, ResourceProviderData, CustomResourceProviderData>))]
	public class CustomResourceProviderData : ResourceProviderData, IHelperAssistedCustomConfigurationData<CustomResourceProviderData>
	{
		#region Fields
		private readonly CustomProviderDataHelper<CustomResourceProviderData> helper;
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets custom configuration attributes.
		/// </summary>
		/// <value>Collection of attribute names and values</value>
		public NameValueCollection Attributes
		{
			get 
			{ 
				helper.Attributes.Set(ResourceProviderData.ResourceBaseNameProperty, ResourceBaseName);
				return helper.Attributes; 
			}
		}

		/// <summary>
		/// Gets a <see cref="ConfigurationPropertyCollection"/> of the properties that are defined for
		/// this configuration element when implemented in a derived class.
		/// </summary>
		/// <value>
		/// A <see cref="ConfigurationPropertyCollection"/> of the properties that are defined for this
		/// configuration element when implemented in a derived class.
		/// </value>
		protected override ConfigurationPropertyCollection Properties
		{
			get { return helper.Properties; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initializes with default values.
		/// </summary>
		public CustomResourceProviderData ()
		{
			helper = new CustomProviderDataHelper<CustomResourceProviderData>(this);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="CustomResourceProviderData"/> class.
		/// </summary>
		/// <param name="name">The provider name.</param>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		private CustomResourceProviderData(string name, string resourceBaseName)
			: this()
		{
			Name = name;
			ResourceBaseName = resourceBaseName;
		}

		/// <summary>
		/// Initializes with name and provider type.
		/// </summary>
		/// <param name="name">The provider name.</param>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		/// <param name="type">The provider type.</param>
		public CustomResourceProviderData(string name, string resourceBaseName, Type type)
			: this(name, resourceBaseName)
		{
			Type = type;
		}

		/// <summary>
		/// Initializes with name and provider type name.
		/// </summary>
		/// <param name="name">The provider name.</param>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		/// <param name="typeName">Name of the type.</param>
		public CustomResourceProviderData(string name, string resourceBaseName, string typeName)
			: this(name, resourceBaseName)
		{
			TypeName = typeName;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Sets the attribute value for a key.
		/// </summary>
		/// <param name="key">The attribute name.</param>
		/// <param name="value">The attribute value.</param>
		public void SetAttributeValue (string key, string value)
		{
			helper.HandleSetAttributeValue(key, value);
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Modifies the <see cref="CustomResourceProviderData"/> object to remove all values that should not be saved. 
		/// </summary>
		/// <param name="sourceElement">A <see cref="ConfigurationElement"/> object at the current level containing a merged view of the properties.</param>
		/// <param name="parentElement">A parent <see cref="ConfigurationElement"/> object or <see langword="null"/> if this is the top level.</param>		
		/// <param name="saveMode">One of the <see cref="ConfigurationSaveMode"/> values.</param>
		protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
		{
			helper.HandleUnmerge(sourceElement, parentElement, saveMode);
		}

		/// <summary>
		/// Resets the internal state of the <see cref="CustomResourceProviderData"/> object, 
		/// including the locks and the properties collection.
		/// </summary>
		/// <param name="parentElement">The parent element.</param>
		protected override void Reset (ConfigurationElement parentElement)
		{
			helper.HandleReset(parentElement);
		}

		/// <summary>
		/// Indicates whether this configuration element has been modified since it was last 
		/// saved or loaded when implemented in a derived class.
		/// </summary>
		/// <returns><see langword="true"/> if the element has been modified; otherwise, <see langword="false"/>. </returns>
		protected override bool IsModified ()
		{
			return helper.HandleIsModified();
		}

		/// <summary>
		/// Called when an unknown attribute is encountered while deserializing the <see cref="CustomResourceProviderData"/> object.
		/// </summary>
		/// <param name="name">The name of the unrecognized attribute.</param>
		/// <param name="value">The value of the unrecognized attribute.</param>
		/// <returns><see langword="true"/> if the processing of the element should continue; otherwise, <see langword="false"/>.</returns>
		protected override bool OnDeserializeUnrecognizedAttribute (string name, string value)
		{
			return helper.HandleOnDeserializeUnrecognizedAttribute(name, value);
		}
		#endregion

		#region Inherited Behaviour
		/// <summary>
		/// Gets the helper.
		/// </summary>
		CustomProviderDataHelper<CustomResourceProviderData> IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.Helper
		{
			get { return helper; }
		}

		/// <summary>Invokes the inherited behavior.</summary>
		object IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.BaseGetPropertyValue (ConfigurationProperty property)
		{
			return base[property];
		}

		/// <summary>Invokes the inherited behavior.</summary>
		void IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.BaseSetPropertyValue (ConfigurationProperty property, object value)
		{
			base[property] = value;
		}

		/// <summary>Invokes the inherited behavior.</summary>
		void IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.BaseUnmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
		{
			base.Unmerge(sourceElement, parentElement, saveMode);
		}

		/// <summary>Invokes the inherited behavior.</summary>
		void IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.BaseReset (ConfigurationElement parentElement)
		{
			base.Reset(parentElement);
		}

		/// <summary>Invokes the inherited behavior.</summary>
		bool IHelperAssistedCustomConfigurationData<CustomResourceProviderData>.BaseIsModified ()
		{
			return base.IsModified();
		}
		#endregion
	}
}